package com.heima.comment.service.impl;

import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentRepay;
import com.heima.comment.pojos.ApCommentRepayLike;
import com.heima.comment.pojos.CommentRepayVo;
import com.heima.comment.service.CommentRepayService;
import com.heima.feigns.user.UserFeign;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.threadlocal.AppThreadLocalUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Version: V1.0
 */
@Service
public class CommentRepayServiceImpl implements CommentRepayService {

    @Autowired
    UserFeign userFeign;

    @Autowired
    MongoTemplate mongoTemplate;

    private final Integer size = 10;

    /**
     * 保存文章评论
     *
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentRepaySaveDto dto) {
        //1 参数校验
        if (dto==null || dto.getCommentId()==null
                || StringUtils.isBlank(dto.getContent()) || dto.getContent().length()>140){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "评论回复不合法");
        }

        //2 获取用户登录状态
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        // 获取用户的对象
        user = userFeign.findApUserById(user.getId());
        if (user == null || user.getStatus()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN,"当前用户不合法");
        }

        //TODO 内容进行阿里云安全审核

        //3 封装数据，执行保存评论
        ApCommentRepay commentRepay = ApCommentRepay.builder()
                .authorId(user.getId())
                .authorName(user.getName())
                .commentId(dto.getCommentId())
                .content(dto.getContent())
                .likes(0)
                .createdTime(new Date())
                .build();
        mongoTemplate.save(commentRepay);

        // 更新评论对应回复数 +1
        ApComment apComment = mongoTemplate.findOne(Query.query(Criteria.where("_id").is(dto.getCommentId())), ApComment.class);
        apComment.setReply(apComment.getReply() + 1);
        mongoTemplate.save(apComment);

        //4 返回结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    /**
     * 评论点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult like(CommentRepayLikeDto dto) {
        //1 参数校验
        if (dto == null || StringUtils.isBlank(dto.getCommentRepayId())
                || dto.getOperation() < 0 || dto.getOperation() > 1) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //2 获取用户登录状态
        ApUser user = AppThreadLocalUtils.getUser();
        if (user == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        //3 判断当前评论是否存在
        ApCommentRepay apCommentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
        if (apCommentRepay == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }

        //5 判断当前用户是否已点赞
        ApCommentRepayLike apCommentRepayLike = mongoTemplate.findOne(
                Query.query(Criteria
                .where("authorId").is(user.getId())
                .and("commentRepayId").is(dto.getCommentRepayId())
        ), ApCommentRepayLike.class);

        if (apCommentRepayLike != null && dto.getOperation() == 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST, "已点赞");
        }


        //4 点赞/取消点赞
        if (dto.getOperation() == 0) {  //点赞
            // 保存点赞
            ApCommentRepayLike commentRepayLike = new ApCommentRepayLike();
            commentRepayLike.setAuthorId(user.getId());
            commentRepayLike.setCommentRepayId(dto.getCommentRepayId());
            commentRepayLike.setOperation(dto.getOperation());
            mongoTemplate.save(commentRepayLike);

            // 更新评论的点赞数 +1
            apCommentRepay.setLikes(apCommentRepay.getLikes() + 1);
            mongoTemplate.save(apCommentRepay);

        }else { // 取消点赞
            // 删除点赞
            Query query = Query.query(Criteria
                    .where("authorId").is(user.getId())
                    .and("commentRepayId").is(dto.getCommentRepayId())
            );
            mongoTemplate.remove(query, ApCommentRepayLike.class);

            // 更新评论的点赞数 -1
            apCommentRepay.setLikes((apCommentRepay.getLikes() - 1 < 0) ? 0 : (apCommentRepay.getLikes() - 1));
            mongoTemplate.save(apCommentRepay);
        }

        //5 返回结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    /**
     * 查询文章评论列表
     * @param dto
     * @return
     */
    @Override
    public ResponseResult load(CommentRepayDto dto) {
        //1 参数校验
        if (dto == null || dto.getCommentId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }
        if (dto.getMinDate() == null) {
            dto.setMinDate(new Date());
        }

        //2 根据评论id查询回复列表
        Query query = Query.query(Criteria
                .where("commentId").is(dto.getCommentId())
                .and("createdTime").lt(dto.getMinDate())
        );
        // 排序
        query.with(Sort.by(Sort.Direction.DESC, "createdTime"));
        // 一页记录数
        query.limit(size);

        List<ApCommentRepay> commentRepayList = mongoTemplate.find(query, ApCommentRepay.class);
        if (commentRepayList == null || commentRepayList.size() == 0) {
            return ResponseResult.okResult();
        }

        //3 获取用户登录状态
        ApUser user = AppThreadLocalUtils.getUser();
        //4 判断用户登录状态  未登录 直接返回评论列表
        if (user == null) {
            return ResponseResult.okResult(commentRepayList);
        }

        //5 已登录， 回显当前用户是否对莫一条评论数据点赞
        //5.1 取所有评论id [1,2,4,5,6]
        List<String> idList = commentRepayList.stream()
                .map(commmentRepay -> commmentRepay.getId()).collect(Collectors.toList());

        //5.2 查询当前评论id下的点赞列表 当前用点赞列表
       List<ApCommentRepayLike> commentRepayLikes = mongoTemplate.find( Query.query(Criteria
                                     .where("commentRepayId").in(idList)
                                     .and("operation").is(0)
                                     .and("authorId").is(user.getId())
                             ) ,
               ApCommentRepayLike.class);

        //5.3 判断封装
        List<CommentRepayVo> commentRepayVos = new ArrayList<>();

        if(commentRepayList!=null && commentRepayList.size()>0 && commentRepayLikes!=null && commentRepayLikes.size()>0){
            commentRepayList.forEach( commentRepay -> {  // 所有的评论
                //***
                CommentRepayVo commentRepayVo = new CommentRepayVo();
                BeanUtils.copyProperties(commentRepay, commentRepayVo);

                commentRepayLikes.forEach( commentRepayLike -> {
                    if (commentRepay.getId().equals(commentRepayLike.getCommentRepayId())) {
                        // 该评论是我已点赞 回显 **
                        commentRepayVo.setOperation(0);
                    }
                });

                // ** 添加到集合
                commentRepayVos.add(commentRepayVo);
            } );

        }else { // 对当前文章评论未点赞
            return ResponseResult.okResult(commentRepayList);
        }


        return ResponseResult.okResult(commentRepayVos);
    }
}
